﻿using Reborn.Infrastructure;
using SimpleSpider.Framework.Model;
using SimpleSpider.Framework.Services.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SimpleSpider.Framework
{
    public abstract class CrawlUrlWorker : SpiderBase
    {
        bool _isStart = false;
        bool isNotData = false;

        StartUrlService _startUrlService = null;
        UrlService _urlService = null;
        public CrawlUrlWorker() {
            _startUrlService = new StartUrlService();
            _urlService = new UrlService();
        }

        public abstract void Handler(StartUrlModel startUrlModel);

        /// <summary>
        /// 保存网址
        /// </summary>
        /// <param name="urlModel"></param>
        /// <returns></returns>
        public int Save(UrlModel urlModel)
        {
            return _urlService.Insert(urlModel);
        }

        /// <summary>
        /// 批量保存网址
        /// </summary>
        /// <param name="urls"></param>
        /// <returns></returns>
        public int Save(List<UrlModel> urls)
        {
            return _urlService.Insert(urls);
        }

        /// <summary>
        /// 是否唯一值
        /// </summary>
        /// <param name="uniqueId"></param>
        /// <returns></returns>
        public bool IsUnique(string uniqueId)
        { 
            return _urlService.GetFirst( x => x.UniqueId == uniqueId) != null ? true : false;
        }

        public void Start()
        { 
            if(_isStart)  return;
            _isStart = true;

            Task.Factory.StartNew(Work);
        }

        void Work()
        {
            while (true)
            {
                try
                {
                    StartUrlModel startUrlModel = Pop();
                    if (startUrlModel == null)
                    {
                        isNotData = true;
                        continue;
                    }

                    isNotData = false;
                    Handler(startUrlModel);

                    startUrlModel.UpdateTime = DateTime.Now;

                    _startUrlService.Update(startUrlModel, t => new { t.Status, t.UpdateTime });
                }
                catch (Exception ex)
                {
                    Logger.Exception(ex);
                }
                finally
                {
                    Thread.Sleep(50);
                }
            }
        }

        StartUrlModel Pop()
        {
            var startUrlResult = _startUrlService.GetFirst(x => x.Status == Reborn.Contracts.State.TaskStatus.WaitingForActivation);
            if (startUrlResult == null) return startUrlResult;

            startUrlResult.UpdateTime = DateTime.Now;
            startUrlResult.Status = Reborn.Contracts.State.TaskStatus.WaitingToRun;

            _startUrlService.Update(startUrlResult, t => new { t.Status, t.UpdateTime });

            return startUrlResult;
        }
    }
}
